package com.hemerasolutions.v2trainer.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.event.ActionEvent;

import org.apache.commons.lang.mutable.MutableInt;
import org.primefaces.event.FileUploadEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.hemerasolutions.v2trainer.controller.interfaces.AdminBeanInterface;
import com.hemerasolutions.v2trainer.model.multimedia.Photo;
import com.hemerasolutions.v2trainer.model.multimedia.RemoteVideo;
import com.hemerasolutions.v2trainer.model.multimedia.Video;
import com.hemerasolutions.v2trainer.model.users.Admin;
import com.hemerasolutions.v2trainer.model.users.User;
import com.hemerasolutions.v2trainer.service.ExceptionService;
import com.hemerasolutions.v2trainer.service.interfaces.LibraryServiceInterface;
import com.hemerasolutions.v2trainer.service.interfaces.MultimediaServiceInterface;
import com.hemerasolutions.v2trainer.service.interfaces.UserServiceInterface;


@Controller
@ManagedBean(name="adminBean")
@Scope("view")
public class AdminBean extends BaseBean implements AdminBeanInterface {


	private static final long serialVersionUID = 1L;

	@Autowired
	private UserServiceInterface userService;
	
	@Autowired
	private LibraryServiceInterface libraryService;
	
	@Autowired 
	private MultimediaServiceInterface multimediaService;
	
	private List<Video> videos;
	
	private transient List<com.google.api.services.youtube.model.Video> ytVideos;
	
	private List<Admin> admins;
	
	private Admin selAdmin;
	
	private Admin admin;
	
	private int uploadType;
	
	private MutableInt videoUploadProgress;
	
	private Date 		begCreatedAt;
    
	private Date 		endCreatedAt;
    
	private Date 		begChangedAt;
    
	private Date 		endChangedAt;

	private String 		findByFirstName;
    
	private String 		findByLastName;

	private String 		findByEmail;
    
	private boolean 	findByStatus = true;	
	
	private RemoteVideo defaultExerciseRemoteVideo;
	
	private RemoteVideo defaultEquipmentRemoteVideo;

	
	public AdminBean() {
		super();
	}

	
	@PostConstruct
	public void init(){
		super.init();
		if(this.getActiveUserType() == User.USERTYPE_ADMIN){
			this.admin = this.getActiveActor(Admin.class);
			this.listAll();
		}	

		this.readDefaultVideos();
		
	}
	
	public void disconnectYouTube(){
		try{
			this.multimediaService.disconnectYouTube();
			this.showInfoMessage(this.localizedText("Success"), this.localizedText("DisconnectedWithSuccess"));
		}catch(ExceptionService ex){
			this.showErrorMessage(this.localizedText("Error"), this.localizedText(ex.getMessage()));
		}
	}	

	public void connectYouTube(){
		try{
			multimediaService.listYouTubeVideos();
			this.showInfoMessage(this.localizedText("Success"), this.localizedText("ConnectedWithSuccess"));
		}catch(ExceptionService ex){
			this.showErrorMessage(this.localizedText("Error"), this.localizedText(ex.getMessage()));
		}
	}
	
	
	public void readDefaultVideos(){
		this.defaultExerciseRemoteVideo = this.multimediaService.readDefaultExerciseRemoteVideo();
		this.defaultEquipmentRemoteVideo = this.multimediaService.readDefaultEquipmentRemoteVideo();
	}
	
	
	public void deleteDefaultEquipmentVideo(){
		try{
			this.multimediaService.deleteDefaultEquipmentVideo();
			this.defaultEquipmentRemoteVideo = this.multimediaService.readDefaultEquipmentRemoteVideo();
		} catch (ExceptionService e) {
			this.showErrorMessage(this.localizedText("DeleteError"), e.getLocalizedMessage());
		}
		
	}
	
	public void deleteDefaultExerciseVideo(){
		try{
			this.multimediaService.deleteDefaultExerciseVideo();
			this.defaultExerciseRemoteVideo = this.multimediaService.readDefaultExerciseRemoteVideo();
		} catch (ExceptionService e) {
			this.showErrorMessage(this.localizedText("DeleteError"), e.getLocalizedMessage());
		}
				
	}

	private void listAll() {

	   	Map<String,Object> fields = new HashMap<String, Object>();
	    this.admins = this.userService.searchAdmins(fields);

	}	
	
	public void clear(){
		this.admin = null;
	}

	
	public void createAdmin(){
		try {
			userService.createAdmin(admin);
			this.showInfoMessage(	this.localizedText("CreatedWithSuccess"),
					this.localizedText("TheAdmin") + " " +
					this.admin.getFirstName() + "\n " + 
					this.localizedText("wasCreatedWithSuccess"));			
			this.admin = null;
			this.listAll();
		} catch (ExceptionService e) {
			this.showErrorMessage(this.localizedText("CreateError"), e.getLocalizedMessage());
			e.printStackTrace();
		}
	}
	
	
	public void saveAdmin(){
		try {
			userService.saveAdmin(admin);
			this.showInfoMessage(	this.localizedText("SavedWithSuccess"),
					this.localizedText("TheAdmin") + " " +
							this.admin.getFirstName() + "\n " + 
					this.localizedText("wasSavedWithSuccess"));			
			this.listAll();
		} catch (ExceptionService e) {
			this.showErrorMessage(this.localizedText("SaveError"), e.getLocalizedMessage());
		}
	}
	
	public void cancelChange(){
		if(this.admin.getId() != 0){
			this.admin = userService.readAdmin(admin);
		}else{
			this.admin = new Admin();
		}
	}

	public void uploadPhoto(FileUploadEvent ev){
		

		Photo photo = new Photo();

		photo.setName("user_photo");
		photo.setHeight(120);
		photo.setWidth(100);
		
		admin.setPhoto(super.uploadPhoto(ev, photo));
		admin.getPhoto().setLocation(userService.persistPhotoInFile(photo));

	}
	
	public void syncRemoteStorage(){
		try{
			if(uploadType == 2){
				this.defaultExerciseRemoteVideo = multimediaService.uploadToYouTube(this.defaultExerciseRemoteVideo, videoUploadProgress);
				this.multimediaService.saveRemoteVideo(this.defaultExerciseRemoteVideo);
			}else if(uploadType == 3){
				this.defaultEquipmentRemoteVideo = multimediaService.uploadToYouTube(this.defaultEquipmentRemoteVideo, videoUploadProgress);
				this.multimediaService.saveRemoteVideo(this.defaultEquipmentRemoteVideo);
			}
		}catch(ExceptionService ex){
			this.showErrorMessage(this.localizedText("Error"),ex.getMessage());
		}
	}
	
	public void uploadVideo(FileUploadEvent ev){
		this.videoUploadProgress = new MutableInt(0);
		
		if(uploadType == 2){

			RemoteVideo rm = this.multimediaService.readDefaultExerciseRemoteVideo();
			
			rm.setUploadedFile(ev.getFile());
			rm.setVideoHascode(rm.calcVideoMD5HashCode());
			
			this.defaultExerciseRemoteVideo = rm;
			
		}else if(uploadType == 3){
			RemoteVideo rm = this.multimediaService.readDefaultEquipmentRemoteVideo();
			
			rm.setUploadedFile(ev.getFile());
			rm.setVideoHascode(rm.calcVideoMD5HashCode());
			
			this.defaultEquipmentRemoteVideo = rm;
		}
	}
	
	public void search(ActionEvent event){

    	Map<String,Object> fields = new HashMap<String, Object>();
    	
		if( this.begCreatedAt != null && this.endCreatedAt != null && 
				this.begCreatedAt.compareTo(this.endCreatedAt) > 0){
				this.showErrorMessage(	this.localizedText("CreationDate"),
										this.localizedText("TheInitialDateNeedToBeGreaterThanFinal"));
				return;
			}
			

		if( this.begChangedAt != null && this.endChangedAt != null && 
			this.begChangedAt.compareTo(this.endChangedAt) > 0){
			this.showErrorMessage(	this.localizedText("ChangeDate"),
									this.localizedText("TheInitialDateNeedToBeGreaterThanFinal"));
			return;			
		}
    	
    	

    	if (!this.findByFirstName.equals("")) {
            fields.put("firstName", this.findByFirstName);
        }

    	if (!this.findByLastName.equals("")) {
            fields.put("lastName", this.findByLastName);
        }

   	
    	if (!this.findByEmail.equals("")){
    		fields.put("email",this.findByEmail);
    	}
    	
    	if (this.begCreatedAt != null){
    		fields.put("begCreatedAt", this.begCreatedAt);
    	}
    	if (this.endCreatedAt != null){
            fields.put("endCreatedAt",this.endCreatedAt);
        }
        if (this.begChangedAt != null){
        	fields.put("begChangedAt",this.begChangedAt);
        }
        if (this.endChangedAt != null){
        	fields.put("endChangedAt", this.endChangedAt);
        }

	    fields.put("active", this.findByStatus);
		
	    this.admins = this.userService.searchAdmins(fields);

		if((this.admins).isEmpty()){
			this.showInfoMessage(	this.localizedText("SearchCompleted"),
									this.localizedText("NoEntrysFounded"));
		}else{
			this.showInfoMessage(	this.localizedText("SearchCompleted"),
									this.admins.size() + " " + 
									this.localizedText("entrysFounded"));
		}
	}
	

	
	public void deleteAdmin(){
		
		try{
			userService.deleteAdmin(admin);
			this.showInfoMessage(	this.localizedText("Deleted"),
									this.localizedText("UserDeletedWithSuccess"));
			this.admins.remove(this.admin);
			this.admin = null;
		}catch(ExceptionService e){
			this.showErrorMessage(this.localizedText("DeleteError"),
					e.getLocalizedMessage());
		}
		
	}
	
	
	public void toAddAdmin(){
		this.admin  = new Admin();
		
		this.admin.setPhoto(userService.readDefaultUserPhoto());

		this.admin.getUser().setLibrarys(libraryService.copyPublicLibrarys());
		
		
	}
	
	public void toAddPhoto(){
		
	}

	
	public void testConnection(){
		try{
			if(multimediaService.testConnection()){
				this.showInfoMessage(this.localizedText("Success"),this.localizedText("ConnectedWithSuccess"));
			}else{
				this.showErrorMessage(this.localizedText("Error"),this.localizedText("RemoteStorageConnectError"));
			}
		}catch (ExceptionService ex){
			this.showErrorMessage(this.localizedText("Error"), ex.getLocalizedMessage());
		}
	}
	
	
	
	public void listVideos(){
		try{
			this.ytVideos = multimediaService.listYouTubeVideos();
			
			if((this.admins).isEmpty()){
				this.showInfoMessage(	this.localizedText("SearchCompleted"),
										this.localizedText("NoEntrysFounded"));
			}else{
				this.showInfoMessage(	this.localizedText("SearchCompleted"),
										this.ytVideos.size() + " " + 
										this.localizedText("entrysFounded"));
			}
		
		}catch (ExceptionService ex){
			this.showErrorMessage(this.localizedText("Error"), ex.getLocalizedMessage());
		}
	}
	
	public List<Admin> getAdmins() {
		return admins;
	}

	public Admin getSelAdmin() {
		return selAdmin;
	}

	public Admin getAdmin() {
		return admin;
	}

	public void setAdmins(List<Admin> admins) {
		this.admins = admins;
	}

	public void setSelAdmin(Admin selAdmin) {
		this.selAdmin = selAdmin;
	}

	public void setAdmin(Admin admin) {
		this.admin = admin;
	}


	public int getUploadType() {
		return uploadType;
	}

	public void setUploadType(int uploadType) {
		this.uploadType = uploadType;
	}


	public Date getBegCreatedAt() {
		return begCreatedAt;
	}

	public Date getEndCreatedAt() {
		return endCreatedAt;
	}

	public Date getBegChangedAt() {
		return begChangedAt;
	}

	public Date getEndChangedAt() {
		return endChangedAt;
	}

	public String getFindByFirstName() {
		return findByFirstName;
	}


	public String getFindByEmail() {
		return findByEmail;
	}


	public boolean isFindByStatus() {
		return findByStatus;
	}

	public void setBegCreatedAt(Date begCreatedAt) {
		this.begCreatedAt = begCreatedAt;
	}

	public void setEndCreatedAt(Date endCreatedAt) {
		this.endCreatedAt = endCreatedAt;
	}

	public void setBegChangedAt(Date begChangedAt) {
		this.begChangedAt = begChangedAt;
	}

	public void setEndChangedAt(Date endChangedAt) {
		this.endChangedAt = endChangedAt;
	}

	public void setFindByFirstName(String findByName) {
		this.findByFirstName = findByName;
	}


	public void setFindByEmail(String findByEmail) {
		this.findByEmail = findByEmail;
	}

	public void setFindByStatus(boolean findByStatus) {
		this.findByStatus = findByStatus;
	}

	public String getFindByLastName() {
		return findByLastName;
	}

	public void setFindByLastName(String findByLastName) {
		this.findByLastName = findByLastName;
	}


	public List<Video> getVideos() {
		return videos;
	}


	public void setVideos(List<Video> videos) {
		this.videos = videos;
	}


	public MutableInt getVideoUploadProgress() {
		return videoUploadProgress;
	}


	public void setVideoUploadProgress(MutableInt videoUploadProgress) {
		this.videoUploadProgress = videoUploadProgress;
	}


	public List<com.google.api.services.youtube.model.Video> getYtVideos() {
		return ytVideos;
	}


	public void setYtVideos(List<com.google.api.services.youtube.model.Video> ytVideos) {
		this.ytVideos = ytVideos;
	}


	public RemoteVideo getDefaultExerciseRemoteVideo() {
		return defaultExerciseRemoteVideo;
	}


	public void setDefaultExerciseVideo(RemoteVideo defaultExerciseRemoteVideo) {
		this.defaultExerciseRemoteVideo = defaultExerciseRemoteVideo;
	}


	public RemoteVideo getDefaultEquipmentRemoteVideo() {
		return defaultEquipmentRemoteVideo;
	}


	public void setDefaultEquipmentVideo(RemoteVideo defaultEquipmentRemoteVideo) {
		this.defaultEquipmentRemoteVideo = defaultEquipmentRemoteVideo;
	}



	
}
